package com.ragdollcat.thirdaicodegenerate.util;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.ragdollcat.thirdaicodegenerate.exception.BusinessException;
import com.ragdollcat.thirdaicodegenerate.exception.ErrorCode;
import io.github.bonigarcia.wdm.WebDriverManager;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.time.Duration;

/**
 * 网页截图工具
 */
@Slf4j
public class WebScreenUtil {

    private WebScreenUtil() {
    }

//    private static final WebDriver webDriver;
//
//    static {
//        final int DEFAULT_WIDTH = 1600;
//        final int DEFAULT_HEIGHT = 900;
//        webDriver = initChromeDriver(DEFAULT_WIDTH, DEFAULT_HEIGHT);
//    }
//
//    @PreDestroy
//    public void destroy() {
//        webDriver.quit();
//    }

    /**
     * 进行截屏操作，压缩，保存到本地
     *
     * @param url
     */
    public static String doWebScreen(String url) {
        WebDriver webDriver = null;
        try {
            if (StrUtil.isBlank(url)) {
                return null;
            }
            //初始化谷歌浏览器驱动
            final int DEFAULT_WIDTH = 1600;
            final int DEFAULT_HEIGHT = 900;
            //使用火狐
            webDriver = initFirefoxDriver(DEFAULT_WIDTH, DEFAULT_HEIGHT);
            //读取链接
            webDriver.get(url);
            //等待网页加载完成
            waitForPageLoad(webDriver);
            //执行截图
            byte[] imageBytes = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.BYTES);

            final String originFilePath = System.getProperty("user.dir") + File.separator + "tmp" + File.separator + "screenShots" + File.separator +
                    RandomUtil.randomNumbers(5) + ".png";
            //保存图片文件
            boolean savedImageResult = saveImage(imageBytes, originFilePath);
            if (!savedImageResult) {
                log.error("保存图片文件失败！保存路径：{}", originFilePath);
                return null;
            }
            //进行图片压缩
            final String targetFilePath = System.getProperty("user.dir") + File.separator + "tmp" + File.separator + "screenShots" + File.separator +
                    RandomUtil.randomNumbers(5) + "_compression.png";
            boolean compressedImageResult = compressedImage(originFilePath, targetFilePath);
            if (!compressedImageResult) {
                log.error("压缩图片错误，原始路径：{}，目标路径：{}", originFilePath, targetFilePath);
                return null;
            }
            //删除原始图片，只保存压缩后的图片
            boolean delOriginFileResult = delOriginFile(originFilePath);
            if (!delOriginFileResult) {
                log.error("删除原始图片失败！{}", originFilePath);
                return null;
            }
            return targetFilePath;
        } catch (Exception e) {
            log.error("网页截图失败！原因：", e);
            return null;
        }finally {
            //释放资源
            assert webDriver != null;
            webDriver.quit();
        }
    }

    public static boolean delOriginFile(String originFilePath) {
        return FileUtil.del(originFilePath);
    }


    /**
     * 等待页面加载完成
     */
    private static void waitForPageLoad(WebDriver driver) {
        try {
            // 创建等待页面加载对象
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            // 等待 document.readyState 为complete
            wait.until(webDriver ->
                    ((JavascriptExecutor) webDriver).executeScript("return document.readyState")
                            .equals("complete")
            );
            // 额外等待一段时间，确保动态内容加载完成
            Thread.sleep(2000);
            log.info("页面加载完成");
        } catch (Exception e) {
            log.error("等待页面加载时出现异常，继续执行截图", e);
        }
    }


    /**
     * 将图片临时保存到文件中
     */
    private static boolean saveImage(byte[] imageBytes, String originFilePath) {
        // D:\Idea_workspace\2025\third-ai-code-generate\tmp\image\12384.png
        try {
            File file = FileUtil.writeBytes(imageBytes, originFilePath);
            return file != null && file.exists();
        } catch (Exception e) {
            log.error("保存图片错误！路径：{}，原因：", originFilePath, e);
            return false;
        }
    }


    /**
     * 压缩图片
     *
     * @param originPath 原始路径
     * @param targetPath 压缩后的路径
     */
    private static boolean compressedImage(String originPath, String targetPath) {
        final float COMPRESSION_RATIO = 0.3f;
        try {
            ImgUtil.compress(FileUtil.file(originPath), FileUtil.file(targetPath), COMPRESSION_RATIO);
        } catch (Exception e) {
            log.error("压缩图片错误，原始路径：{}，目标路径：{}，原因：", originPath, targetPath, e);
            return false;
        }
        return true;
    }


    /**
     * 初始化 Firefox 浏览器驱动
     */
    private static WebDriver initFirefoxDriver(int width, int height) {
        try {
            // 自动管理 GeckoDriver（Firefox 的驱动）
            WebDriverManager.firefoxdriver().setup();

            // 配置 Firefox 选项
            FirefoxOptions options = new FirefoxOptions();

            // 无头模式（Firefox 对应的无头参数）
            options.addArguments("-headless");

            // 禁用GPU
            options.addArguments("--disable-gpu");

            // 禁用沙盒模式
            options.addArguments("--no-sandbox");

            // 设置窗口大小
            options.addArguments(String.format("--width=%d", width));
            options.addArguments(String.format("--height=%d", height));

            // 禁用扩展
            options.addArguments("--disable-extensions");

            // 设置用户代理
            options.addPreference("general.useragent.override",
                    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/102.0");

            // 创建驱动
            WebDriver driver = new FirefoxDriver(options);

            // 设置页面加载超时
            driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30));

            // 设置隐式等待
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

            return driver;
        } catch (Exception e) {
            log.error("初始化 Firefox 浏览器失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "初始化 Firefox 浏览器失败");
        }
    }


}
